package com.moyun.syssecurity.handler;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.moyun.common.utils.JwtTokenUtil;
import com.moyun.common.utils.SpringContextUtil;
import com.moyun.model.po.system.SysUserEntity;
import lombok.AllArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.LinkedHashMap;

/**
 * <h3>learning_route</h3>
 * <p>自定义登录成功处理器，用于登录成功后的处理</p>
 *
 * @author : ybx
 * @date : 2021-01-24 19:22:36
 **/
@Component
@AllArgsConstructor
public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler {

    private final RedisTemplate<String, Object> redisTemplate;
    private final ObjectMapper objectMapper;
    private static String ONLINE_USERS = "ONLINE_USERS";

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        JwtTokenUtil jwtTokenUtil = SpringContextUtil.getBean(JwtTokenUtil.class);
        response.setContentType("application/json; charset=UTF-8");
        PrintWriter out = response.getWriter();
        HashMap<String, Object> map = new HashMap<>();
        map.put("code", HttpServletResponse.SC_OK);
        map.put("msg", "欢迎登录系统");

        SecurityContextHolder.getContext().setAuthentication(authentication);
        // 生成jwt令牌
        String token = jwtTokenUtil.generateToken((SysUserEntity) authentication.getPrincipal());
        LinkedHashMap<String, Object> linkedHashMap = new LinkedHashMap<>();
        linkedHashMap.put("token", token);
        SysUserEntity principal = (SysUserEntity) authentication.getPrincipal();
        principal.setUserPassword(null);
        linkedHashMap.put("userInfo", principal);
        map.put("data", linkedHashMap);
//        out.write(JSON.toJSONString(map));
        out.write(objectMapper.writeValueAsString(map));
        // 获取用户名
        String username = principal.getUsername();
         this.redisTemplate.opsForValue().set(ONLINE_USERS + username, token);
         response.setHeader("jwtToken",token);

        // 可选配置,将token放入到cookie中,可减少客户端对Header的操作  开发适用
        setCookie(token, response);
        // 可选配置,将个别信息放到Httpsession对象中
//        setAttribute(request, principal);
        out.flush();
        out.close();
    }

    /**
     * @return void
     * @Author yangboxuan
     * @Description 将生成的token保存到cookie中
     * @Date 2021/6/30 10:32
     * @Param [token, response]
     **/
    private void setCookie(String token, HttpServletResponse response) {
        // 将JWT写入Cookie，用于减少客户端对Header的操作(该步骤为可选项)
//        Cookie cookie = new Cookie(Constants.JWT, token);
        Cookie cookie = new Cookie("jwtToken", token);
        cookie.setPath("/");
        response.addCookie(cookie);
    }

    /**
     * @return void
     * @Author yangboxuan
     * @Description 设置 HttpSession 的属性
     * @Date 2021/9/4 19:04
     * @Param [request]
     */
    private void setAttribute(HttpServletRequest request, SysUserEntity principal) {
        HttpSession session = request.getSession();
        session.setAttribute("uid", principal.getId());
    }
}
